﻿//////////////////////////////////////////////////
//                   Monk.cs                    //
//         Part of RebornCo by kaihaider        //
//////////////////////////////////////////////////
using System.Threading.Tasks;
using ff14bot;
using ff14bot.Enums;
using ff14bot.Objects;
using RebornCo.Helpers;
using RebornCo.Settings;
using TreeSharp;

namespace RebornCo.Rotations
{
    public class Monk : RebornCoRoutine
    {
        public override void OnInitialize()
        {
            WantHealing = false;
            WindowSettings = new PugSetting();
        }
        public static PugSetting PugSettings
        {
            get { return WindowSettings as PugSetting; }
        }
        public sealed override ClassJobType[] Class
        {
            get
            {
                return new [] 
                { 
                    ClassJobType.Monk
                };
            }
        }
        [Behavior(BehaviorType.PreCombatBuffs, ClassJobType.Monk)]
        public Composite MonkCreateBasicPreCombatBuffs()
        {
            return new ActionRunCoroutine(ctx => MonkBuildPreCombatBuffs());
        }
        public static async Task<bool> MonkBuildPreCombatBuffs()
        {
            if (!IsValid()) return false;
            if (Resting)
            {
                if (!Core.Player.IsCasting && await Spell.Cast("Cure", Core.Player, Core.Player.CurrentHealthPercent < 70 && Core.Player.CurrentHealthPercent < Core.Player.CurrentManaPercent)) return true;
                if (!Core.Player.IsCasting && await Spell.Cast("Physick", Core.Player, Core.Player.CurrentHealthPercent < 70 && Core.Player.CurrentHealthPercent < Core.Player.CurrentManaPercent)) return true;
                return false;
            }
            if (await Spell.BuffParty("Protect")) return true;
            if (await Spell.BuffParty("Stoneskin")) return true;
            return await CombatCompanion();
        }
        [Behavior(BehaviorType.Rest, ClassJobType.Monk)]
        public Composite MonkCreateBasicRest()
        {
            return new ActionRunCoroutine(ctx => DefaultRestBehavior(Core.Player.CurrentTPPercent)); 
        }
        [Behavior(BehaviorType.CombatBuffs, ClassJobType.Monk)]
        public Composite MonkCreateBasicCombatBuffs()
        {
            return new ActionRunCoroutine(ctx => MonkBuildCombatBuffs()); 
        }
        public static async Task<bool> MonkBuildCombatBuffs()
        {//add fists of wind && mantra
            ShouldPulse = true;
            if (await Spell.Cast("Cure", Core.Player, Core.Player.CurrentHealthPercent < 40)) return true;
            if (await Spell.Cast("Physick", Core.Player, Core.Player.CurrentHealthPercent < 40)) return true;
            if (await Spell.Cast("Fists of Fire", Core.Player, (Core.Player.CurrentHealth > 30 || !Core.Player.HasAura("Fists of Earth"))
                && !Core.Player.HasAura("Fists of Fire"), false, true, true)) return true;
            if (await Spell.Cast("Fists of Earth", Core.Player, (Core.Player.CurrentHealth < 30 || !Core.Player.HasAura("Fists of Fire"))
                && !Core.Player.HasAura("Fists of Earth"), false, true, true)) return true;
            if (Spell.GcdTime < PugSettings.NoneGcdWindowEnd) return false;
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Invigorate", Core.Player, Core.Player.CurrentTPPercent < 50))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Eye for an Eye", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Foresight", Core.Player, !Core.Player.HasAura("Foresight")))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Blood for Blood", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Internal Release", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (WindowSettings.CooldownsUsable && Spell.Potion != null && Spell.Potion.IsValid
                && Spell.Potion.CanUse(Core.Player) && Spell.Potion.Name.Equals(WindowSettings.PotionName))
            {
                Spell.Potion.UseItem(Core.Player);
                if (WindowSettings.PotionForce) Spell.UsedNoneGcd = true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Quelling Strikes", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Hawk's Eye", Core.Player))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Bloodbath", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Raging Strikes", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Keen Flurry", Core.Player, Core.Player.CurrentHealthPercent < 80))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Foresight", Core.Player, Core.Player.CurrentHealthPercent < 60))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Convalescence", Core.Player, Core.Player.CurrentHealthPercent < 70))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Second Wind", Core.Player, Core.Player.CurrentHealthPercent < 40))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Awareness", Core.Player, Core.Player.CurrentHealthPercent < 30))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Featherfoot", Core.Player, Core.Player.Distance2D() < 5))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            return false;
        }
        [Behavior(BehaviorType.Pull, ClassJobType.Monk)]
        public Composite MonkCreateBasicPull()
        {
            return new ActionRunCoroutine(ctx => MonkBuildPullBehavior()); 
        }
        public static async Task<bool> MonkBuildPullBehavior()
        {
            if (Core.Player.CurrentTarget != null && !Core.Player.CurrentTarget.CanAttack || !IsValid()) return false;
            ShouldPulse = true;
            await Target.EnsureValidTarget();
            if (await Movement.PullMove(Core.Player.CurrentTarget)) return true;
            if (PugSettings.WaitEnergyPull && Core.Player.CurrentTPPercent < PugSettings.RestEnergy)
            {
                ff14bot.Helpers.Logging.Write("[RebornCo] Waiting for energy before pull!");
                return true;
            }
            if (!Spell.Gcd && Core.Player.HasAura("Raptor Form"))
            {
                if (await Spell.PullCast("Twin Snakes", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.IsBehind
                    || !Core.Player.HasAura("Twin Snakes"))) return true;
                if (await Spell.PullCast("True Strike", Core.Player.CurrentTarget)) return true;
            }
            if (!Spell.Gcd && Core.Player.HasAura("Coeurl Form"))
            {
                if (await Spell.PullCast("Demolish", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && 
                            !Core.Player.CurrentTarget.HasAura("Demolish",true))) return true; //
                if (await Spell.PullCast("Snap Punch", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.IsFlanking))
                    return true;
                if (await Spell.PullCast("Demolish", Core.Player.CurrentTarget)) return true;
                if (await Spell.PullCast("Snap Punch", Core.Player.CurrentTarget)) return true;
            }
            return await Spell.PullCast("Bootshine", Core.Player.CurrentTarget);
            // return false;
        }

        [Behavior(BehaviorType.Combat, ClassJobType.Monk)]
        public Composite MonkCreateBasicCombat()
        {
            return new ActionRunCoroutine(ctx => MonkBuildBasicCombat()); 
        }
        public static async Task<bool> MonkBuildBasicCombat()
        {//intterupt Arm of the Destroyer in Opo-opoform
            //add shoulder tackle
            //straight shot cross skill
            await Target.EnsureValidTarget();
            await Movement.MoveToTarget();
            if (Core.Player.CurrentTarget != null && ff14bot.Managers.MovementManager.IsMoving
                && !(Core.Player.CurrentTarget.InLineOfSight() && Core.Player.CurrentTarget.Distance2D() < Movement.ObjectMeleeRange(Core.Player.CurrentTarget))) return true;

            if (!Spell.Gcd && Core.Player.CurrentTarget != null && Core.Player.HasAura("Coeurl Form")
                && !Core.Player.HasAura("Greased Lightning", true, 3))
            {
                if (await Spell.CastLock("Rockbreaker", Core.Player.CurrentTarget,
                            Core.Player.CurrentTarget.Distance2D() < 5 && PugSettings.Aoe && Target.EnemiesNearTarget(5) >= PugSettings.AoeCount)) return true;
                if (await Spell.CastLock("Snap Punch", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.IsFlanking)) return true;
                if (await Spell.CastLock("Demolish", Core.Player.CurrentTarget, Core.Player.CurrentTarget.CurrentHealthPercent > PugSettings.MinDotHp
                    && (Core.Player.CurrentTarget.IsFlanking && !Core.Player.CurrentTarget.HasAura("Demolish")
                       || !Core.Player.CurrentTarget.IsFlanking && !Core.Player.CurrentTarget.HasAura("Demolish", true, PugSettings.DemolishClip)))) return true;
                if (await Spell.CastLock("Rockbreaker", Core.Player.CurrentTarget, Core.Player.CurrentTarget.Distance2D() < 5)) return true;
                if (await Spell.CastLock("Snap Punch", Core.Player.CurrentTarget)) return true;
            }

            if (!Spell.Gcd && await Spell.CastLock("Touch of Death", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null
                && Core.Player.CurrentTarget.CurrentHealthPercent > PugSettings.MinDotHp
                       && !Core.Player.CurrentTarget.HasAura("Touch of Death", true, PugSettings.TouchOfDeathClip)))return true;
            if (!Spell.Gcd && Core.Player.HasAura("Perfect Balance"))
            {//possible rockbreaker
                if (await Spell.CastLock("Demolish", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.CurrentHealthPercent > PugSettings.MinDotHp
                       && !Core.Player.CurrentTarget.HasAura("Demolish",true,PugSettings.DemolishClip))) return true;
                if (await Spell.CastLock("Twin Snakes", Core.Player.CurrentTarget, !Core.Player.HasAura("Twin Snakes", false, PugSettings.TwinSnakesClip))) return true;
                if (await Spell.CastLock("Snap Punch", Core.Player.CurrentTarget)) return true;
            }
            if (!Spell.Gcd && await Spell.CastLock("Virus", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && (Core.Player.CurrentTarget as Character) != null &&
                        !(Core.Player.CurrentTarget as Character).HasAura("Virus"))) return true;
            if (!Spell.Gcd && await Spell.CastLock("Steel Peak", Core.Player.CurrentTarget)) return true; //gcd?
            if (!Spell.Gcd && await Spell.CastLock("Howling Fist", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && PugSettings.Aoe && Target.EnemiesNearTarget((float)2.5) >= PugSettings.AoeCount
                && Core.Player.CurrentTarget.Distance2D() > Movement.MeleeRange + 3 && Core.Player.CurrentTarget.Distance2D() < 10f)) return true; //range
            if (!Spell.Gcd && await Spell.CastLock("Venomous Bite", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null
                        && !Core.Player.CurrentTarget.HasAura("Venomous Bite",true))) return true;
            if (!Spell.Gcd && await Spell.CastLock("Fracture", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && (Core.Player.CurrentTarget as Character) != null
                        && !(Core.Player.CurrentTarget as Character).HasAura("Fracture"))) return true;
            if (!Spell.Gcd && Core.Player.HasAura("Raptor Form"))
            {//One Ilm Punch - check if target has buff to remove
                if (await Spell.CastLock("Twin Snakes", Core.Player.CurrentTarget, Core.Player.CurrentTarget.IsFlanking ||  
                    !Core.Player.HasAura("Twin Snakes", false, PugSettings.TwinSnakesClip))) return true;
                if (await Spell.CastLock("True Strike", Core.Player.CurrentTarget)) return true;
            }
            if (!Spell.Gcd && Core.Player.CurrentTarget != null && Core.Player.HasAura("Coeurl Form"))
            {
                if (await Spell.CastLock("Rockbreaker", Core.Player.CurrentTarget,
                            Core.Player.CurrentTarget.Distance2D() < 5 && PugSettings.Aoe && Target.EnemiesNearTarget(5) >= PugSettings.AoeCount)) return true;
                if (await Spell.CastLock("Snap Punch", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.IsFlanking)) return true;
                if (await Spell.CastLock("Demolish", Core.Player.CurrentTarget, Core.Player.CurrentTarget.CurrentHealthPercent > PugSettings.MinDotHp
                    && (Core.Player.CurrentTarget.IsFlanking && !Core.Player.CurrentTarget.HasAura("Demolish")
                       || !Core.Player.CurrentTarget.IsFlanking && !Core.Player.CurrentTarget.HasAura("Demolish", true, PugSettings.DemolishClip)))) return true;
                if (await Spell.CastLock("Rockbreaker", Core.Player.CurrentTarget, Core.Player.CurrentTarget.Distance2D() < 5)) return true;
                if (await Spell.CastLock("Snap Punch", Core.Player.CurrentTarget)) return true;
            }
            if (!Spell.Gcd && Core.Player.HasAura("Opo-opo Form"))
            {
                if (await Spell.CastLock("Dragon Kick", Core.Player.CurrentTarget, Core.Player.CurrentTarget.IsFlanking || !Core.Player.CurrentTarget.HasAura("Dragon Kick", true))) return true;
            }
            // if (await Spell.CastLock("Dragon Kick", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.IsFlanking)) return true;
 //           if (!Gcd && await Spell.Cast("Haymaker", Core.Player.CurrentTarget, PugSettings.UseHaymaker && Core.Player.CurrentTarget != null && (!Core.Player.CurrentTarget.IsBehind || !Core.Player.CurrentTarget.IsFlanking))) didSomething = true;
            if (!Spell.Gcd && await Spell.CastLock("Bootshine", Core.Player.CurrentTarget, !(Core.Player.HasAura("Raptor Form") || Core.Player.HasAura("Coeurl Form") || Core.Player.HasAura("Perfect Balance")))) return true;

            if (Spell.GcdTime < PugSettings.NoneGcdWindowEnd) return false;
            if (!Spell.UsedNoneGcd && await Spell.Cast("Perfect Balance", Core.Player, PugSettings.CooldownsUsable && !Core.Player.HasAura("Perfect Balance"), false, true, true))
            {
                Spell.UsedNoneGcd = true;
                if (await Spell.CastLock("Demolish", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.CurrentHealthPercent > PugSettings.MinDotHp
                    && (Core.Player.CurrentTarget.IsFlanking && !Core.Player.CurrentTarget.HasAura("Demolish")
                       || !Core.Player.CurrentTarget.IsFlanking && !Core.Player.CurrentTarget.HasAura("Demolish", true, PugSettings.DemolishClip)))) return true;
                if (await Spell.CastLock("Twin Snakes", Core.Player.CurrentTarget, !Core.Player.HasAura("Twin Snakes", false, PugSettings.TwinSnakesClip))) return true;
                if (await Spell.CastLock("Snap Punch", Core.Player.CurrentTarget)) return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Mercy Stroke", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.CurrentHealthPercent < 20))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            return false;
        }

    }
}
